﻿

namespace Huirui.Cavan.Presentation.Seedwork
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.Contracts;
    using System.Linq;
    using System.Web.Mvc;
    using System.Web.Routing;
    using Huirui.Cavan.Core.Extension;

    public class AopUrlHelper : UrlHelper, IUrlHelper
    {
        #region members
        #endregion members

        #region const
        public const string RouteValuePrefix = "__RouteValuePrefix_";
        #endregion const

        #region constructor
        public AopUrlHelper(RequestContext requestContext)
            : base(requestContext) { }

        public AopUrlHelper(RequestContext requestContext, RouteCollection routeCollection)
            : base(requestContext, routeCollection) { }
        #endregion constructor

        #region new (override)
        public new virtual string Action(string actionName)
        {
            return base.Action(actionName, null, MergeRouteValues(null));
        }

        public new virtual string Action(string actionName, object routeValues)
        {
            return base.Action(actionName, null, MergeRouteValues(routeValues));
        }

        public new virtual string Action(string actionName, string controllerName)
        {
            return base.Action(actionName, controllerName, MergeRouteValues(null));
        }

        public new virtual string Action(string actionName, RouteValueDictionary routeValues)
        {
            return base.Action(actionName, null, MergeRouteValues(routeValues));
        }

        public new virtual string Action(string actionName, string controllerName, object routeValues)
        {
            return base.Action(actionName, controllerName, MergeRouteValues(routeValues));
        }

        public new virtual string Action(string actionName, string controllerName, RouteValueDictionary routeValues)
        {
            return base.Action(actionName, controllerName, MergeRouteValues(routeValues));
        }

        public new virtual string Action(string actionName, string controllerName, object routeValues, string protocol)
        {
            return Action(actionName, controllerName, MergeRouteValues(routeValues), protocol, null).Replace("&",
                "&amp;");
        }

        public new virtual string Action(string actionName, string controllerName, RouteValueDictionary routeValues,
            string protocol, string hostName)
        {
            return base.Action(actionName, controllerName, MergeRouteValues(routeValues), protocol, hostName);
        }
        #endregion new (override)

        #region protected
        protected virtual RouteValueDictionary MergeRouteValues(object routeValues)
        {
            var dictionary = routeValues as IDictionary<string, object>;
            if (dictionary.IsNull())
            {
                dictionary = routeValues.Is()
                                 ? new RouteValueDictionary(routeValues)
                                 : new RouteValueDictionary();
            }

            var list = RequestContext.RouteData.Values
                .Where(p => p.Key.StartsWith(RouteValuePrefix, StringComparison.Ordinal))
                .ToList();
            foreach (var pair in list)
            {
                var key = pair.Key.Replace(RouteValuePrefix, string.Empty);
                object value;
                if (!dictionary.TryGetValue(key, out value))
                {
                    dictionary[key] = pair.Value;
                }
            }

            return new RouteValueDictionary(dictionary);
        }
        #endregion protected
    }
}